package com.dingding.study.service.自定义注解操作数据库;

import com.alibaba.fastjson.JSONObject;
import com.dingding.study.annotation.DataItem;
import com.dingding.study.constant.ResourceType;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Field;
import java.util.List;
import java.util.Map;

/**
 * @author liugongding
 * @description:
 * @date 2023/5/4 10:22 PM
 */

@Component
@Slf4j
public class DataItemInterceptor implements HandlerInterceptor {

    @Autowired
    private CacheLoadingUtil cacheLoadingUtil;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        if (handler instanceof HandlerMethod) {
            HandlerMethod handlerMethod = (HandlerMethod) handler;
            //获取当前拦截的类的class
            Class<?> beanType = handlerMethod.getBeanType();
            //获取当前拦截类对应的对象
            Object bean = handlerMethod.getBean();
            //拦截对应对象下所有的字段
            Field[] fields = beanType.getDeclaredFields();
            if (fields.length > 0) {
                for (Field field : fields) {
                    if (field.isAnnotationPresent(DataItem.class)) {
                        field.setAccessible(true);
                        //TODO 判断field类型这里只给String赋值
                        //字段定义的名称
                        //String name = field.getName();
                        //PropertyDescriptor propertyDescriptor = BeanUtils.getPropertyDescriptor(bean.getClass(), name);
                        ////获取set方法赋值
                        //Method setMethod = propertyDescriptor.getWriteMethod();
                        //Method readMethod = propertyDescriptor.getReadMethod();
                        //setMethod.invoke(bean, "dingding");
                        DataItem dataItemAnnotion = field.getAnnotation(DataItem.class);
                        String key = dataItemAnnotion.key();
                        ResourceType type = dataItemAnnotion.type();
                        String data = cacheLoadingUtil.get(key);
                        if (StringUtils.isNotBlank(data)) {
                            field.set(bean, transformer(type, data));
                        }
                    }
                }
            }
        }
        return true;
    }

    private Object transformer(ResourceType type, String data) {
        Object object = null;
        switch (type) {
            case STRING:
                object = data;
                break;
            case MAP:
                object = JSONObject.parseObject(data, Map.class);
                break;
            case LIST:
                object = JSONObject.parseObject(data, List.class);
                break;
            default:break;
        }
        return object;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
    }
}
